package com.hdu.dwh.controller;


import com.hdu.dwh.annotation.RequirePermission;
import com.hdu.dwh.dao.PaimonBaseDao;
import com.hdu.dwh.dtos.DataWarehouseTableDto;
import com.hdu.dwh.dtos.TablePageDto;
import com.hdu.dwh.exception.CustomException;
import com.hdu.dwh.exception.DataNotFoundException;
import com.hdu.dwh.pojos.PaimonTag;
import com.hdu.dwh.pojos.source_access_pojos.DataWarehouseTable;
import com.hdu.dwh.service.DataWarehouseTableService;
import com.hdu.dwh.service.ModelService;
import com.hdu.dwh.service.cube_service.CubeService;
import com.hdu.dwh.vos.dataWareHouse_vos.DataWarehouseTableDetailVo;
import com.hdu.dwh.results.ResponseResult;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;

import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;


/**
 * <p>
 * 源数据表表 前端控制器
 * </p>
 *
 * @author bobo
 * @since 2025-04-08
 */
@RestController
@RequestMapping("/dwh/table")
@RequiredArgsConstructor
@Tag(name = "湖仓数据表管理")
public class DataWarehouseTableController {

    private final PaimonBaseDao paimonBaseDao;

    private final DataWarehouseTableService dwhTableService;
    @Autowired
    private CubeService cubeService;

    @Autowired
    private ModelService modelService;

    @Operation(summary ="新增源数据表")
    @PostMapping("/add")
    public ResponseResult<?> add(@Valid @RequestBody DataWarehouseTableDto sourceTableDto) {
        return dwhTableService.add(sourceTableDto);
    }

    @RequirePermission("model.delete")
    @Operation(summary ="删除源数据表")
    @DeleteMapping("/delete/{id}")
    public ResponseResult<?> delete(@PathVariable Long id) throws DataNotFoundException {
        DataWarehouseTable table = this.dwhTableService.getById(id);
        if (table == null) {
            throw new DataNotFoundException("datawarehouse_table","数据表不存在");
        }
        if(table.getHierarchy() == 0 || table.getHierarchy() == 4) {
            dwhTableService.deleteTable(table);
        } else if(table.getHierarchy() == 3) {
            this.cubeService.deleteCuboidByTableId(id);
        } else if(table.getHierarchy() == 2) {
            this.modelService.deleteModelByTableId(id);
        }

        return ResponseResult.success();
    }

    @Operation(summary ="查询详细信息")
    @GetMapping("/{id}")
    public ResponseResult<DataWarehouseTableDetailVo> getDetilById(@PathVariable Long id) throws Exception {
        return ResponseResult.success(dwhTableService.getDetilById(id));
    }

    @Operation(summary ="查资产详情(分页)")
    @PostMapping("/page")
    public ResponseResult<?> page(@Valid @RequestBody TablePageDto tablePageDto){
        return dwhTableService.detilPage(tablePageDto);
    }

    @Operation(summary ="查询所有数据表")
    @GetMapping("/table")
    public ResponseResult<?> getTable(@RequestParam(required = false) Long databaseId, @RequestParam(required = false) String databaseName, @RequestParam(required = false) Integer hierarchy) {
        return dwhTableService.getTable(databaseId, databaseName, hierarchy);
    }

    @Operation(summary = "添加tag")
    @PostMapping("/tag/{tableId}/{tag}")
    public ResponseResult<?> addTag(@PathVariable Integer tableId, @PathVariable String tag) {
        DataWarehouseTable table = this.dwhTableService.getById(tableId);
        this.dwhTableService.addTag(table, tag);
        return ResponseResult.success();
    }

    @Operation(summary = "删除tag")
    @DeleteMapping("/tag/{tableId}/{tag}")
    public ResponseResult<?> deleteTag(@PathVariable Integer tableId, @PathVariable String tag) {
        DataWarehouseTable table = this.dwhTableService.getById(tableId);
        this.dwhTableService.deleteTag(table, tag);
        return ResponseResult.success();
    }

    @Operation(summary = "查看tag")
    @GetMapping("/tag")
    public ResponseResult<Set<PaimonTag>> fetchTags(@RequestParam Integer tableId) {
        DataWarehouseTable table = this.dwhTableService.getById(tableId);
        Set<PaimonTag> tags = this.dwhTableService.fetchTags(table);
        return ResponseResult.success(tags);
    }

    @Operation(summary = "回滚到tag")
    @PostMapping("/tag/rollback/{tableId}/{tag}")
    public ResponseResult<?> rollBackTag(@PathVariable Integer tableId, @PathVariable String tag) {
        DataWarehouseTable table = this.dwhTableService.getById(tableId);
        this.dwhTableService.rollBackToTag(table, tag);
        return ResponseResult.success();
    }
    
    @Operation(summary = "表格溯源")
    @PostMapping("/trace/{tableId}")
    public ResponseResult<Map<String, Set<DataWarehouseTable>>> trace(@PathVariable Integer tableId) {
        DataWarehouseTable table = this.dwhTableService.getById(tableId);
        Set<DataWarehouseTable> traceUpSet = this.dwhTableService.traceUp(table);
        Set<DataWarehouseTable> traceDownSet = this.dwhTableService.traceDown(table);
        return ResponseResult.success(Map.of(
            "traceUpSet", traceUpSet,
            "traceDownSet", traceDownSet
        ));
    }

    @Operation(summary = "删除表格(paimon)")
    @DeleteMapping("/paimon/delete/{database}/{table}")
    public ResponseResult<?> deletePaimonTable(@PathVariable String table, @PathVariable String database) throws CustomException {
        this.paimonBaseDao.deleteTable(database, table);
        return ResponseResult.success("删除成功");
    }

    @Operation(summary = "删除表格(数据库管理信息)")
    @DeleteMapping("/dwh/delete/{database}/{table}")
    public ResponseResult<?> deleteDwhTable(@PathVariable String table, @PathVariable String database) throws CustomException {
        DataWarehouseTable dwhTable = this.dwhTableService.getPaimonTableByDatabaseAndTableName(database, table);
        dwhTableService.deleteTable(dwhTable);
        return ResponseResult.success("删除成功");
    } 
    
}
